1 /*
2 * Title: S/MIME Project
3 * Description: S/MIME email sending capabilities
4 * @Author Vladimir Radisic
5 * @Version 2.0.1
6 */
7
8
9 package org.webdocwf.util.smime.activation;
10
11
12 import org.webdocwf.util.smime.crypto.SymmetricEncryption;
13 import org.webdocwf.util.smime.cms.*;
14 import org.webdocwf.util.smime.util.MimeAssist;
15 import org.webdocwf.util.smime.util.MimeAssist;
16 import org.webdocwf.util.smime.exception.SMIMEException;
17 import org.webdocwf.util.smime.exception.SMIMEIOException;
18 import javax.mail.internet.MimeMessage;
19 import java.security.cert.X509Certificate;
20 import javax.activation.DataSource;
21 import java.io.*;
22
23
24 /***
25 * CMSEnvelopedDataSource represents implementation of DataSource interfaces. It
26 * is used within MimeMessage as a source of data. Also, object of this class is
27 * used to create DER encoded Cryptographic Message Syntax (CMS) object
28 * represented in ASN.1 notation according to RFC2630. This object (CMS) is used
29 * as the source of data for MimeMessage in the process of sending encrypted message.
30 */
31 public class CMSEnvelopedDataSource implements DataSource {
32
33 /***
34 * Container for encrypted content information
35 */
36 private EncryptedContentInfo encContInf;
37
38 /***
39 * Container for RecipientInfos
40 */
41 private RecipientInfos recInf;
42
43 /***
44 * Constructs CMS object for encryption with MIME Message in form of
45 * byte array and with given values for encryption algorithm.
46 * @param message0 message for encryption
47 * @param algType0 given symmetric algorithm for encryption
48 * @param keyLength0 key length in bits
49 * @exception SMIMEException in case of unrecognized type of symmetryc
50 * algorithm or invalid key length. Also, it can be caused by problems in
51 * construction or work with some inner objects instantiated from classes
52 * that belong to org.webdocwf.util.smime.der or org.webdocwf.util.smime.cms
53 * packages used in other CMSEnvelopedDataSource constructor.
54 */
55 public CMSEnvelopedDataSource(byte[] message0, String algType0, int keyLength0) throws SMIMEException {
56 encContInf = new EncryptedContentInfo();
57 SymmetricEncryption symEnc = new SymmetricEncryption(algType0, keyLength0); // Engine for symmetric encryption - setting symetric algorythm type and algorythm parameters (key length)
58
59 symEnc.encryption(message0); // algType0 can be one of following strings (representing symetric algorithm type): "DESede","RC2","DES"
60 Content encryptedContent = new Content(symEnc.getEncryptedValue(), false); // Creating the Encrypted Content
61 AlgorithmIdentifier contentEncryptAlgID;
62
63 if (algType0.equalsIgnoreCase("RC2_CBC")) // Using RC2 algorithm and appropriate parameter
64 {
65 contentEncryptAlgID = new AlgorithmIdentifier("RC2_CBC", "NAME_STRING");
66 RC2CBCParameter par = new RC2CBCParameter(symEnc.getKeyLength(), symEnc.getIV());
67
68 contentEncryptAlgID.addParamToAlgorithmId(par.getDEREncoded()); // Creating the Content Encryption Algorithm Identifier
69 } else if (algType0.equalsIgnoreCase("DES_EDE3_CBC")) // Using DES EDE3 algorithm and appropriate parameter
70 {
71 contentEncryptAlgID = new AlgorithmIdentifier("DES_EDE3_CBC", "NAME_STRING");
72 DESede3CBCParameter par = new DESede3CBCParameter(symEnc.getIV());
73
74 contentEncryptAlgID.addParamToAlgorithmId(par.getDEREncoded()); // Creating the Content Encryption Algorithm Identifier
75 } else if (algType0.equalsIgnoreCase("DES")) // Using DES algorithm and appropriate parameter
76 {
77 contentEncryptAlgID = new AlgorithmIdentifier("DES", "NAME_STRING");
78 DESede3CBCParameter par = new DESede3CBCParameter(symEnc.getIV()); // Same parameter as for DES EDE algorithm
79
80 contentEncryptAlgID.addParamToAlgorithmId(par.getDEREncoded()); // Creating the Content Encryption Algorithm Identifier
81 } else
82 throw new SMIMEException(this, 1013);
83 ContentTypeIdentifier contentData = new ContentTypeIdentifier("ID_DATA", "NAME_STRING"); // Creating the Content Type
84
85 encContInf.addContentType(contentData.getDEREncoded());
86 encContInf.addEncryptAlgorithmID(contentEncryptAlgID.getDEREncoded());
87 encContInf.addEncryptContent(encryptedContent.getDEREncoded());
88 recInf = new RecipientInfos(symEnc.getSymmetricKey()); // Initialization of Recipient Infos with RC2 symetric key
89 }
90
91 /***
92 * Constructs CMS object for encryption with MIME Message in form of
93 * instance of MimeMessage class and with defined values for encryption algorithm.
94 * @param message0 message for encryption
95 * @param algType0 given symmetric algorithm for encryption
96 * @param keyLength0 key length in bits
97 * @exception SMIMEException in case of unrecognized type of symmetryc
98 * algorithm, invalid key length or in case of failure in MimeMessageConvertor
99 * class which performes transformation from MimeMessage object to byte array.
100 * Also, it can be caused by problems in construction or work with some
101 * inner objects instantiated from classes that belong to
102 * org.webdocwf.util.smime.der or org.webdocwf.util.smime.cms packages used
103 * in other CMSEnvelopedDataSource constructor.
104 */
105 public CMSEnvelopedDataSource(MimeMessage message0, String algType0, int keyLength0) throws SMIMEException {
106 this(MimeAssist.messageConvertor(message0), algType0, keyLength0);
107 }
108
109 /***
110 * Adds recipient. This method must be performed at least once.
111 * @param cert0 recipient's X509Certificate (.cer file).
112 * @exception SMIMEException caused by addRecipient method of inner object
113 * which is instance of class RecipientInfos.
114 */
115 public void addRecipient(X509Certificate cert0) throws SMIMEException {
116 recInf.addRecipient(cert0);
117 }
118
119 /***
120 * Returns complete DER encoded CMS Enveloped Object.
121 * @return DER encoded CMS Enveloped Object represented as byte array
122 * @exception SMIMEException caused by problems in construction or work
123 * with some inner objects instantiated from classes that belong to
124 * org.webdocwf.util.smime.der or org.webdocwf.util.smime.cms packages.
125 */
126 public byte[] getCMSEnvelopedObject() throws SMIMEException {
127 ContentTypeIdentifier contentTypeEnvelopDataId = new ContentTypeIdentifier("ID_ENVELOPEDDATA", "NAME_STRING"); // Creating the Content Type
128 EnvelopedData envData = new EnvelopedData(); // Container for enveloped data sub object
129
130 envData.addCMSVersion(new CMSVersion(0).getDEREncoded());
131 envData.addRecipientInfos(recInf.getDEREncoded());
132 envData.addEncryptContentInfo(encContInf.getDEREncoded());
133 Content cont = new Content(envData.getDEREncoded(), true); // Filling enveloped data content in context specific DER object
134 ContentInfo cmsObjectEnvelopedData = new ContentInfo();
135
136 cmsObjectEnvelopedData.addContentType(contentTypeEnvelopDataId.getDEREncoded());
137 cmsObjectEnvelopedData.addContent(cont.getDEREncoded());
138 return cmsObjectEnvelopedData.getDEREncoded();
139 }
140
141 /***
142 * Returns complete DER encoded CMS Enveloped Object with BASE64 encoding
143 * @return DER encoded CMS Enveloped Object represented as byte array with
144 * performed BASE64 encoding
145 * @exception SMIMEException in case of failure in Base64 encoding performed
146 * on the generated SMIME message byte array by Base64ForMime class. Also, it
147 * can be caused by problems in construction or work with some inner objects
148 * instantiated from classes that belong to org.webdocwf.util.smime.der or
149 * org.webdocwf.util.smime.cms packages used in getCMSEnvelopedObject() method.
150 */
151 public byte[] getBASE64CMSEnvelopedObject() throws SMIMEException {
152 return MimeAssist.getBASE64WithBreakOn76(this.getCMSEnvelopedObject());
153 }
154
155 /***
156 * Implements getContentType method from DataSource interface
157 * @return Content-Type for MIME message header field
158 */
159 public String getContentType() {
160 // For new version of mail clients: "application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
161 return "application/x-pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
162 }
163
164 /***
165 * Implements getInputStream method from DataSource interface
166 * @return CMS enveloped object
167 * @exception SMIMEIOException thrown as result of SMIMEException
168 */
169 public InputStream getInputStream() throws SMIMEIOException {
170 try {
171 return new ByteArrayInputStream(getCMSEnvelopedObject());
172 } catch (SMIMEException e) {
173 throw new SMIMEIOException(e);
174 }
175 }
176
177 /***
178 * ImplementS getName method from DataSource interface
179 * @return Name: EnvelopedDataContentInfo
180 */
181 public String getName() {
182 return "EnvelopedDataContentInfo";
183 }
184
185 /***
186 * Implements getOutputStream method from DataSource interface. This method is
187 * not in use.
188 * @return nothing
189 * @exception IOException is always thrown when this method is used.
190 */
191 public OutputStream getOutputStream() throws IOException {
192 throw new IOException("EnvelopedDataContentInfo does not support getOutputStream()");
193 }
194 }
195
This page was automatically generated by Maven